package com.l2jserver.gameserver.instancemanager;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.URL;
import java.util.Collection;

import javolution.util.FastList;


import com.l2jserver.Config;

import com.l2jserver.gameserver.Announcements;
import com.l2jserver.gameserver.ThreadPoolManager;
import com.l2jserver.gameserver.model.L2ItemInstance;
import com.l2jserver.gameserver.model.L2World;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;

public class AutoVoteRewardHandler
{
	@SuppressWarnings("unused")
	private static AutoVoteRewardHandler _instance;
	
	private int			initialCheck			= 1 * 60000;																																																	// 60 seconds = 1 minutes
	private int			delayForCheck			= Config.VOTE_DELAY_FOR_CHECK * 60000;																																																	// 300 seconds = 10 minutes
	//HopZone
	private String		HOPZONE					= Config.HOPZONE_VOTE_EVENT_SITE;
	private int			HopZonereward1Id		= Config.HOPZONE_VOTE_REWARD_ITEM_ID;
	private int			HopZonereward1Count		= Config.HOPZONE_VOTE_REWARD_ITEM_COUNT;
	private int			HopZonevotesForReward	= Config.HOPZONE_VOTE_FOR_REWARD;
	private int			HopZonemaxRewardStack	= Config.HOPZONE_VOTE_MAX_STUCK_ITEM_COUNT;
	private int			HopZonelastVoteCount	= 0;
	//GameSites200
	private String		GS200					= Config.GS200_VOTE_EVENT_SITE;
	private int 		GS200rewardId 			= Config.GS200_VOTE_REWARD_ITEM_ID;
	private long 		GS200rewardCount		= Config.GS200_VOTE_REWARD_ITEM_COUNT;
	private int 		GS200votesForReward		= Config.GS200_VOTE_FOR_REWARD;
	private int 		GS200maxRewardStack 	= Config.GS200_VOTE_MAX_STUCK_ITEM_COUNT;
	private int			GS200lastVoteCount 		= 0;
	//GamesitesTop100
	private String		GT100					= Config.GT100_VOTE_EVENT_SITE;
	private int 		GT100rewardId 			= Config.GT100_VOTE_REWARD_ITEM_ID;
	private long 		GT100rewardCount		= Config.GT100_VOTE_REWARD_ITEM_COUNT;
	private int 		GT100votesForReward		= Config.GT100_VOTE_FOR_REWARD;
	private int 		GT100maxRewardStack 	= Config.GT100_VOTE_MAX_STUCK_ITEM_COUNT;
	private int			GT100lastVoteCount 		= 0;
	//TopGameSites
	private String		TGS					= Config.TGS_VOTE_EVENT_SITE;
	private int 		TGSrewardId 			= Config.TGS_VOTE_REWARD_ITEM_ID;
	private long 		TGSrewardCount		= Config.TGS_VOTE_REWARD_ITEM_COUNT;
	private int 		TGSvotesForReward		= Config.TGS_VOTE_FOR_REWARD;
	private int 		TGSmaxRewardStack 	= Config.TGS_VOTE_MAX_STUCK_ITEM_COUNT;
	private int			TGSlastVoteCount 		= 0;
	//TopZone
	private String		TZ					= Config.TZ_VOTE_EVENT_SITE;
	private int 		TZrewardId 			= Config.TZ_VOTE_REWARD_ITEM_ID;
	private long 		TZrewardCount		= Config.TZ_VOTE_REWARD_ITEM_COUNT;
	private int 		TZvotesForReward		= Config.TZ_VOTE_FOR_REWARD;
	private int 		TZmaxRewardStack 	= Config.TZ_VOTE_MAX_STUCK_ITEM_COUNT;
	private int			TZlastVoteCount 		= 0;
	
	private AutoVoteRewardHandler()
	{
		System.out.println("Vote Reward System Initiated.");
		ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(new AutoReward(), initialCheck, delayForCheck);
	}
	
	private class AutoReward implements Runnable
	{
		public void run()
		{
			System.out.println("Vote Count Check.");
			if (Config.ALLOW_HOPZONE_VOTE_REWARD)
			{
				HopzoneCheck();
			}
			if(Config.ALLOW_GS200_VOTE_REWARD)
			{
				GS200check();
			}
			if(Config.ALLOW_GT100_VOTE_REWARD)
			{
				GT100check();
			}
			if(Config.ALLOW_TGS_VOTE_REWARD)
			{
				TGScheck();
			}
			if(Config.ALLOW_TZ_VOTE_REWARD)
			{
				TZcheck();
			}
		}
	}
		
		private void HopzoneCheck()
		{
			if (HopZonereward1Id == 0 || HopZonereward1Count == 0)
			{
				System.out.println("Hopzone Vote Rewards aren't identified.");
				return;
			}
			int hopZone = getHopZoneVotes();
			System.out.println("Hopzone Votes:" + hopZone);
			if (hopZone != 0 && getLastHopzoneVoteCount() != 0 && hopZone >= getLastHopzoneVoteCount() + HopZonevotesForReward)
			{
				FastList<InetAddress> ip = new FastList<InetAddress>();
				Collection<L2PcInstance> pls = L2World.getInstance().getAllPlayers().values();
				for (L2PcInstance player : pls)
				{
					if (player != null)
					{
						L2ItemInstance item1 = player.getInventory().getItemByItemId(HopZonereward1Id);
						if (item1 == null || item1.getCount() < HopZonemaxRewardStack)
						{
							InetAddress ipc = player.getClient().getConnection().getInetAddress();
						       
						       if(ip.contains(ipc))
						        continue;
						       
						       ip.add(ipc);
							player.addItem("reward", HopZonereward1Id, HopZonereward1Count, player, true);
							player.sendMessage("Hopzone Votes Complete! You got 5 Vote Crystal!");
						}
					}
				}
				
				setLastHopzoneVoteCount(getLastHopzoneVoteCount() + HopZonevotesForReward);
			}
			//Announcements.getInstance().announceToAll("Hopzone : " + hopZone + " Votes " );
			//Announcements.getInstance().announceToAll("Next Reward will be on " + (getLastHopzoneVoteCount() + HopZonevotesForReward) + " Votes." );
			if (getLastHopzoneVoteCount() == 0)
			{
				setLastHopzoneVoteCount(hopZone);
			}
		}

		private void GS200check()
	{
		if (GS200rewardId == 0 || GS200rewardCount == 0)
		{
			System.out.println("GS200 Vote Rewards aren't identified.");
			return;
		}
		int GS200 = getGS200Votes(this.GS200);
		System.out.println("GS200 Votes:" + GS200);
		if (GS200 != 0 && GS200lastVoteCount != 0 && GS200 >= GS200lastVoteCount + GS200votesForReward)
		{
			FastList<InetAddress> ip = new FastList<InetAddress>();
			Collection<L2PcInstance> pls = L2World.getInstance().getAllPlayers().values();
			for (L2PcInstance player : pls)
			{
				if (player != null)
				{
					InetAddress i = player.getClient().getConnection().getInetAddress();
					if(ip.contains(i))
						continue;
					ip.add(i);

					L2ItemInstance item1 = player.getInventory().getItemByItemId(GS200rewardId);
					if (item1 == null || item1.getCount() < GS200maxRewardStack)
					{
						player.addItem("reward", GS200rewardId, GS200rewardCount, player, true);
						player.sendMessage("GameSites200 Votes Complete! You got 3 Vote Crystal!");
					}
				}
			}
			setGS200VoteCount(getGS200VoteCount() + GS200votesForReward);
		}
		//Announcements.getInstance().announceToAll("GameSite200: " + GS200 + " Votes | Next Reward on " + (GS200lastVoteCount + GS200votesForReward) + " Votes.");
		if (getGS200VoteCount() == 0)
			{
				setGS200VoteCount(GS200);
			}
	}
	
	private void GT100check()
	{
		if (GT100rewardId == 0 || GT100rewardCount == 0)
		{
			System.out.println("GT100 Vote Rewards aren't identified.");
			return;
		}
		int GT100 = getGT100Votes();
		System.out.println("GT100 Votes:" + GT100);
		if (GT100 != 0 && GT100lastVoteCount != 0 && GT100 >= GT100lastVoteCount + GT100votesForReward)
		{
			FastList<InetAddress> ip = new FastList<InetAddress>();
			Collection<L2PcInstance> pls = L2World.getInstance().getAllPlayers().values();
			for (L2PcInstance player : pls)
			{
				if (player != null)
				{
					InetAddress i = player.getClient().getConnection().getInetAddress();
					if(ip.contains(i))
						continue;
					ip.add(i);

					L2ItemInstance item1 = player.getInventory().getItemByItemId(GT100rewardId);
					if (item1 == null || item1.getCount() < GT100maxRewardStack)
					{
						player.addItem("reward", GT100rewardId, GT100rewardCount, player, true);
						player.sendMessage("GTop 100 Votes Complete! You got 3 Vote Crystal!");
					}
				}
			}
			setGT100VoteCount(getGT100VoteCount() + GT100votesForReward);
		}
		//Announcements.getInstance().announceToAll("GameTop100: " + GT100 + " Votes | Next Reward on " + (GT100lastVoteCount + GT100votesForReward) + " Votes.");
		if (getGT100VoteCount() == 0)
			{
				setGT100VoteCount(GT100);
			}
	}
	
	private void TGScheck()
	{
		if (TGSrewardId == 0 || TGSrewardCount == 0)
		{
			System.out.println("TGS Vote Rewards aren't identified.");
			return;
		}
		int TGS = getTGSVotes();
		System.out.println("TGS Votes:" + TGS);
		if (TGS != 0 && TGSlastVoteCount != 0 && TGS >= TGSlastVoteCount + TGSvotesForReward)
		{
			FastList<InetAddress> ip = new FastList<InetAddress>();
			Collection<L2PcInstance> pls = L2World.getInstance().getAllPlayers().values();
			for (L2PcInstance player : pls)
			{
				if (player != null)
				{
					InetAddress i = player.getClient().getConnection().getInetAddress();
					if(ip.contains(i))
						continue;
					ip.add(i);

					L2ItemInstance item1 = player.getInventory().getItemByItemId(TGSrewardId);
					if (item1 == null || item1.getCount() < TGSmaxRewardStack)
					{
						player.addItem("reward", TGSrewardId, TGSrewardCount, player, true);
						player.sendMessage("TopGameSites Votes Complete! You got 3 Vote Crystal!");
					}
				}
			}
			setTGSVoteCount(getTGSVoteCount() + TGSvotesForReward);
		}
		//Announcements.getInstance().announceToAll("TopGameSites: " + TGS + " Votes | Next Reward on " + (TGSlastVoteCount + TGSvotesForReward) + " Votes.");
		if (getTGSVoteCount() == 0)
			{
				setTGSVoteCount(TGS);
			}
	}
	
	private void TZcheck()
	{
		if (TZrewardId == 0 || TZrewardCount == 0)
		{
			System.out.println("TZ Vote Rewards aren't identified.");
			return;
		}
		int TZ = getTZVotes();
		System.out.println("TZ Votes:" + TZ);
		if (TZ != 0 && TZlastVoteCount != 0 && TZ >= TZlastVoteCount + TZvotesForReward)
		{
			FastList<InetAddress> ip = new FastList<InetAddress>();
			Collection<L2PcInstance> pls = L2World.getInstance().getAllPlayers().values();
			for (L2PcInstance player : pls)
			{
				if (player != null)
				{
					InetAddress i = player.getClient().getConnection().getInetAddress();
					if(ip.contains(i))
						continue;
					ip.add(i);
					L2ItemInstance item1 = player.getInventory().getItemByItemId(TZrewardId);
					if (item1 == null || item1.getCount() < TZmaxRewardStack)
					{
						player.addItem("reward", TZrewardId, TZrewardCount, player, true);
						player.sendMessage("TopZone Votes Complete! You get 5 Vote Crystal!");
					}
				}
			}
			setTZVoteCount(getTZVoteCount() + TZvotesForReward);
		}
		//Announcements.getInstance().announceToAll("TopZone: " + TZ + " Votes | Next Reward on " + (TZlastVoteCount + TZvotesForReward) + " Votes.");
		//Announcements.getInstance().announceToAll("Vote and get Rewards !" );
		if (getTZVoteCount() == 0)
			{
				setTZVoteCount(TZ);
			}	
	}
	
	private int getHopZoneVotes()
	{
		URL url = null;
		InputStreamReader isr = null;
		BufferedReader in = null;
		try
		{
			url = new URL(HOPZONE);
			isr = new InputStreamReader(url.openStream());
			in = new BufferedReader(isr);
			String inputLine;
			int voteCount = 0;
			while ((inputLine = in.readLine()) != null)
			{
				if (inputLine.contains("moreinfo_total_rank_text"))
				{
					voteCount = Integer.valueOf(inputLine.split(">")[2].replace("</div", ""));
					break;
				}
			}
			return voteCount;
		}
		catch (IOException e)
		{
			e.printStackTrace();
			return 0;
		}
		finally
		{
			try
			{
				in.close();
			}
			catch (IOException e)
			{}
			try
			{
				isr.close();
			}
			catch (IOException e)
			{}
		}
	}

	private int getGT100Votes()
	{
		URL url = null;
		InputStreamReader isr = null;
		BufferedReader in = null;
		try
		{
			int voteCount = 0;
			{
				url = new URL(GT100);
				isr = new InputStreamReader(url.openStream());
				in = new BufferedReader(isr);
				String inputLine;
				boolean check = false;
				while ((inputLine = in.readLine()) != null)
				{
					if(inputLine.contains("L2Eternity Freya Sever"))
						check = true;
					else if (check && inputLine.contains("<label><font color=\"#2CBA00\">"))
					{
						voteCount = Integer.valueOf(inputLine.split("<label><font color=\"#2CBA00\">")[1].substring(0,3));
						break;
					}
				}
			}
			return voteCount;
		}
		catch (IOException e)
		{
			e.printStackTrace();
			return 0;
		}
		finally
		{
			try
			{
				in.close();
			}
			catch (IOException e)
			{}
			try
			{
				isr.close();
			}
			catch (IOException e)
			{}
		}
	}
	
	private int getGS200Votes(String urlString)
	{
		if(urlString == null)
		{
			System.out.println("Couldnt read votes in any of the 4 GS200 Pages");
			return 0;
		}
		
		URL url = null;
		InputStreamReader isr = null;
		BufferedReader in = null;
		boolean advance = true;
		try
		{
			int voteCount = 0;
			{
				url = new URL(urlString);
				isr = new InputStreamReader(url.openStream());
				in = new BufferedReader(isr);
				String inputLine;
				while ((inputLine = in.readLine()) != null)
				{
					if (inputLine.contains("details-15364.html"))
					{
						voteCount = Integer.valueOf(inputLine.split("</td><td>")[1].replace("</td><td>", ""));
						advance = false;
						break;
					}
				}
			}
			if(advance)
				return getGS200Votes(getNextGS200Page(urlString));
			return voteCount;
		}
		catch (IOException e)
		{
			e.printStackTrace();
			return 0;
		}
		finally
		{
			try
			{
				in.close();
			}
			catch (IOException e)
			{}
			try
			{
				isr.close();
			}
			catch (IOException e)
			{}
		}
	}
	
	private String getNextGS200Page(String last)
	{
		if(last.endsWith("index2.shtml"))
			return "http://www.gamesites200.com/lineage2/index3.shtml";
		else if(last.contains("index3.shtml"))
			return "http://www.gamesites200.com/lineage2/index4.shtml";
		else if(last.endsWith("/lineage2/"))
			return "http://www.gamesites200.com/lineage2/index2.shtml";
		else
			return null;
	}
	
	private int getTGSVotes()
	{
		URL url = null;
		InputStreamReader isr = null;
		BufferedReader in = null;
		try
		{
			int voteCount = 0;
			{
				url = new URL(TGS);
				isr = new InputStreamReader(url.openStream());
				in = new BufferedReader(isr);
				String inputLine;
				boolean check = false;
				while ((inputLine = in.readLine()) != null)
				{
					if(inputLine.contains("<b>L2 Eternity</b></a>"))
						check = true;
					else if (check && inputLine.contains("<td class=\"list-score1\"><span class=\"score-text\">In:</span><br />"))
					{
						voteCount = Integer.valueOf(in.readLine().split("</td>")[0].trim());
						break;
					}
				}
			}
			return voteCount;
		}
		catch (IOException e)
		{
			e.printStackTrace();
			return 0;
		}
		finally
		{
			try
			{
				in.close();
			}
			catch (IOException e)
			{}
			try
			{
				isr.close();
			}
			catch (IOException e)
			{}
		}
	}
	
	private int getTZVotes()
	{
		URL url = null;
		InputStreamReader isr = null;
		BufferedReader in = null;
		try
		{
			int voteCount = 0;
			{
				url = new URL(TZ);
				isr = new InputStreamReader(url.openStream());
				in = new BufferedReader(isr);
				String inputLine;
				boolean check = false;
				while ((inputLine = in.readLine()) != null)
				{
					if(inputLine.contains("style=\"text-decoration:none;\">"))
					{
						if(inputLine.contains("L2Eternity"))
							check = true;
						else
							check = false;
					}
					else if (check && inputLine.contains("<img src=\"http://l2topzone.com/images/flags"))
					{
						voteCount = Integer.valueOf(in.readLine().split("\"center\">")[1].replaceAll("</div></td>", "").trim());
						break;
					}
				}
			}
			return voteCount;
		}
		catch (IOException e)
		{
			e.printStackTrace();
			return 0;
		}
		finally
		{
			try
			{
				in.close();
			}
			catch (IOException e)
			{}
			try
			{
				isr.close();
			}
			catch (IOException e)
			{}
		}
	}
	
	private void setLastHopzoneVoteCount(int voteCount)
	{
		HopZonelastVoteCount = voteCount;
	}
	
	private int getLastHopzoneVoteCount()
	{
		return HopZonelastVoteCount;
	}
	
	private void setTZVoteCount(int voteCount)
	{
		TZlastVoteCount = voteCount;
	}
	
	private int getTZVoteCount()
	{
		return TZlastVoteCount;
	}
	
	private void setGT100VoteCount(int voteCount)
	{
		GT100lastVoteCount = voteCount;
	}
	
	private int getGT100VoteCount()
	{
		return GT100lastVoteCount;
	}
	
	private void setTGSVoteCount(int voteCount)
	{
		TGSlastVoteCount = voteCount;
	}
	
	private int getTGSVoteCount()
	{
		return TGSlastVoteCount;
	}
	
	private void setGS200VoteCount(int voteCount)
	{
		GS200lastVoteCount = voteCount;
	}
	
	private int getGS200VoteCount()
	{
		return GS200lastVoteCount;
	}
	
	public static AutoVoteRewardHandler getInstance()
	{
		return SingletonHolder._instance;
	}
	
	@SuppressWarnings("synthetic-access")
	private static class SingletonHolder
	{
		protected static final AutoVoteRewardHandler	_instance	= new AutoVoteRewardHandler();
	}
	
	public static void reload()
	{
		_instance	= new AutoVoteRewardHandler();
	}
}
